import {
  HostBinding,
  Component,
  OnInit,
  ViewChild,
  Input,
  Renderer2,
  forwardRef,
  Injector,
  Inject,
  DoCheck,
  OnDestroy,
  ChangeDetectorRef
} from "@angular/core";
import {
  Observable,
  Subject,
  ReplaySubject,
  from,
  of,
  range,
  BehaviorSubject
} from "rxjs";
import { Router } from "@angular/router";
import {
  AsyncValidator,
  NG_ASYNC_VALIDATORS,
  ValidationErrors,
  AbstractControl,
  FormBuilder,
  FormGroup,
  Validators,
  ControlValueAccessor,
  NG_VALUE_ACCESSOR,
  FormControl
} from "@angular/forms";
import { Actions } from "@ngrx/effects";

import { PLATFORM_ID, APP_ID } from "@angular/core";
import { isPlatformServer } from "@angular/common";
import { EhAnimateService } from "@/share/services/eh-animate.service";
import { MatSelect } from "@angular/material";
import { take, takeUntil } from "rxjs/operators";
import {
  LocaleService,
  TranslationService,
  Language,
  DefaultLocale
} from "angular-l10n";
import { MatPaginator, MatSort, MatTableDataSource } from "@angular/material";

import { Store, select } from "@ngrx/store";
import * as fromAssets from "@/assets/store/reducers/index";
import * as fromTrade from "@/trade/store/reducers/index";
import * as fromUser from "@/user/store/reducers/index";
import * as fromRoot from "@/reducers/index";
import { UserActions } from "@/user/store/actions";
import { map, filter, skip, switchMap } from "rxjs/operators";
import { Subscription, combineLatest } from "rxjs";
import { AssetsActions } from "@/assets/store/actions";
import { combineAll, debounceTime } from "rxjs/operators";

import { ActivatedRoute } from "@angular/router";
import {
  ISelectWithdrawAddressRequest,
  IAddAddressRequest
} from "@/assets/store/models/assets";

import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from "@angular/material";

export interface DialogData {
  coin: string;
}

interface IAddressItem {
  coin: string;
  remark: string;
  address: string;
  id: string;
}

@Component({
  selector: "app-address",
  templateUrl: "./address.component.html",
  styleUrls: ["./address.component.scss"]
})
export class AddressComponent implements OnInit, OnDestroy {
  @HostBinding("style.height")
  public height = "100%";

  @Language() lang: string;

  locale = "";

  @DefaultLocale() defaultLocale: string;

  displayedColumns: string[] = ["coin", "address", "remark", "action"];

  lists: Array<IAddressItem> = [];

  addressItem: IAddressItem;

  dataSource;

  validateForm: FormGroup;

  timer;

  @ViewChild("email")
  email;

  @ViewChild("sliderCodeRef")
  sliderCodeRef;

  isServer: boolean;

  @ViewChild(MatSort) sort: MatSort;

  @ViewChild(MatPaginator) paginator: MatPaginator;

  sub$ = {
    defaultLocaleChanged$: null,
    form$: null,
    withdrawAddressListsSub$: null,
    coinValueChangesSub$: null,
    queryParamsSub$: null,
    addressListsSub$: null,
    userSub$: null,
    querySub$: null
  };

  query = {
    coin: ""
  };

  constructor(
    updates$: Actions,
    @Inject(PLATFORM_ID) private platformId: Object,
    private fb: FormBuilder,
    private renderer: Renderer2,
    @Inject("RegService") private regService,
    @Inject("UtilsService") private utilsService,
    @Inject("UserService") private userService,
    @Inject("MsgService") private msgService,
    @Inject("HasUsernameValidatorService") private hasUsernameValidatorService,
    private router: Router,
    private store: Store<fromAssets.State | fromUser.State | fromRoot.State>,
    private changeDetectorRef: ChangeDetectorRef,
    public localeIns: LocaleService,
    private activatedRoute: ActivatedRoute,
    @Inject("DialogService") private dialogService,
    public dialogRef: MatDialogRef<AddressComponent>,
    @Inject(MAT_DIALOG_DATA) public data: DialogData
  ) {
    this.isServer = isPlatformServer(this.platformId);
    this.locale = this.localeIns.getCurrentLocale();
  }

  user$ = this.store.pipe(
    select(fromRoot.user),
    filter(user => !!user)
  );

  req: IAddAddressRequest = {
    coin: "",
    address: "",
    remark: "",
    uid: ""
  };

  selectWithdrawAddressReq: ISelectWithdrawAddressRequest = {
    uid: "",
    coin: ""
  };

  withdrawAddressLists$ = this.store
    .pipe(select(fromRoot.withdrawAddressLists))
    .pipe(filter(withdrawAddressLists => !!withdrawAddressLists));

  ngOnInit(): void {
    this.initForm();
    this.addListen();
  }

  close() {
    this.dialogRef.close();
  }

  addListen() {
    this.sub$.defaultLocaleChanged$ = this.localeIns.defaultLocaleChanged.subscribe(
      () => {
        this.locale = this.localeIns.getCurrentLocale();
      }
    );
    this.sub$.form$ = this.validateForm.valueChanges.subscribe(e => {
      this.req.coin = e.coin;
      this.req.address = e.address;
      this.req.remark = e.remark;
    });
    this.sub$.withdrawAddressListsSub$ = this.withdrawAddressLists$.subscribe(
      withdrawAddressLists => {
        this.dataSource = new MatTableDataSource(withdrawAddressLists);
        this.dataSource.paginator = this.paginator;
        this.dataSource.sort = this.sort;
      }
    );
    this.sub$.coinValueChangesSub$ = this.validateForm.controls.coin.valueChanges.subscribe(
      e => {
        // this.router.navigate(["assets/address"], {
        //   queryParams: { coin: e }
        // });
      }
    );

    this.sub$.querySub$ = this.activatedRoute.queryParams.subscribe(query => {
      const { coin } = query;
      this.query.coin = coin;
      this.validateForm.controls.coin.setValue(coin);
    });

    this.sub$.userSub$ = this.user$.subscribe(e => {
      // this.req.uid = e.id;
    });

    this.sub$.addressListsSub$ = combineLatest(
      this.user$,
      this.activatedRoute.queryParams
    ).subscribe(([user, query]) => {
      const { coin } = query;
      if (!!coin) {
        this.selectWithdrawAddressReq = {
          coin,
          uid: user.id
        };
        this.initWithdrawAddressLists();
      }
    });
  }

  debounce(fn, time = 1000) {
    if (this.timer) {
      clearTimeout(this.timer);
    }
    this.timer = setTimeout(() => {
      fn();
      clearTimeout(this.timer);
    }, time);
  }

  initWithdrawAddressLists() {
    this.store.dispatch(
      new AssetsActions.SelectWithdrawAddress({
        req: this.selectWithdrawAddressReq,
        cpt: this
      })
    );
  }

  initForm() {
    this.validateForm = this.fb.group({
      remark: [null],
      address: [null, Validators.required],
      coin: [null, Validators.required]
    });
  }

  // here don't need add address
  onChangeCoin(e) {
    if (e.coin !== this.query.coin) {
      this.router.navigate(["/assets/withdraw"], {
        queryParams: {
          coin: e.coin
        }
      });
    }
  }

  onSubmit() {
    // 验证码如果验证失败可以重置
    this.store.dispatch(
      new AssetsActions.AddAddress({ req: this.req, cpt: this })
    );
  }

  onDel(e) {
    this.dialogService
      .confirm("confirm.del")
      .afterClosed()
      .subscribe(b => {
        if (!b) {
          return;
        }
        this.store.dispatch(
          new AssetsActions.DelAddress({ req: { id: e.id }, cpt: this })
        );
      });
  }

  ngOnDestroy() {
    this.utilsService.unsub(this.sub$);
  }
}
